package ch.zbw.swt.sysventory.network.scan;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

import ch.zbw.swt.sysventory.hibernate.entity.Computer;
import ch.zbw.swt.sysventory.hibernate.entity.Nic;
import ch.zbw.swt.sysventory.hibernate.entity.OperatingSystem;
import ch.zbw.swt.sysventory.hibernate.entity.Printer;
import ch.zbw.swt.sysventory.hibernate.entity.Processor;
import ch.zbw.swt.sysventory.hibernate.entity.Software;
import ch.zbw.swt.sysventory.hibernate.entity.Volume;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.jacob.com.EnumVariant;
import com.jacob.com.Variant;

public class ScanComputer implements Callable<Computer> {

	// Initialise Data Types

	public String hostNameComputer;
	public String sidComputer;
	public String ramComputer;
	public String typeComputer;
	public OperatingSystem os;
	public Processor processor;
	public List<Software> softwares;
	public List<Nic> nics;
	public List<Printer> printers;

	private Computer computer;
	private String host;

	// Constructor
	public ScanComputer(String host) {
		this.host = host;
	}

	public Computer call() throws Exception {
		return getComputer();
	}

	// Get Coputerdata
	public Computer getComputer() {
		try {

			String connectStr = String.format("winmgmts:\\\\%s\\root\\CIMV2",
					host);
			String query = "SELECT * FROM Win32_ComputerSystem";
			// Load Librarys
			ActiveXComponent axWMI = new ActiveXComponent(connectStr);

			// Execute the query
			Variant vCollection = axWMI.invoke("ExecQuery", new Variant(query));

			// Das Resultat ist eine Datensammlung
			EnumVariant enumVariant = new EnumVariant(vCollection.toDispatch());
			Dispatch item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();

				hostNameComputer = Dispatch.call(item, "Name").toString();
				long ramTemp = Long
						.valueOf(
								(Dispatch.call(item, "TotalPhysicalMemory"))
										.toString()).longValue();

				final long MEGABYTE = 1024L * 1024L;
				ramComputer = String.valueOf(ramTemp / MEGABYTE);

				int typ = 0;
				try {
					String strTyp = Dispatch.call(item, "PCSystemType")
							.toString();
					typ = Integer.parseInt(strTyp);
				} catch (Exception e) {
				}

				switch (typ) {
				case 0:
					typeComputer = "Unspecified";
					break;
				case 1:
					typeComputer = "Desktop";
					break;
				case 2:
					typeComputer = "Mobile";
					break;
				case 3:
					typeComputer = "Workstation";
					break;
				case 4:
					typeComputer = "Enterprise Server";
					break;
				case 5:
					typeComputer = "mall Office and Home Office (SOHO) Server";
					break;
				case 6:
					typeComputer = "Appliance PC";
					break;
				case 7:
					typeComputer = "Performance Server";
					break;
				case 8:
					typeComputer = "Maximum";
					break;
				default:
					typeComputer = "Unspecified";
					break;
				}
			}

			// SID query
			query = "SELECT * from Win32_UserAccount WHERE Name='Administrator' AND LocalAccount=True";
			vCollection = axWMI.invoke("ExecQuery", new Variant(query));
			enumVariant = new EnumVariant(vCollection.toDispatch());
			item = null;
			while (enumVariant.hasMoreElements()) {
				item = enumVariant.nextElement().toDispatch();
				sidComputer = Dispatch.call(item, "SID").toString();
				if (sidComputer.length() > 0 && sidComputer.indexOf("-") > 0) {
					sidComputer.substring(0, sidComputer.lastIndexOf("-"));
				}
			}

			computer = new Computer();
			computer.setScanedHost(host);

			ScanOperatingSystem scanOs = new ScanOperatingSystem(computer);
			OperatingSystem os = scanOs.getOperatingSystem(host);

			ScanProcessor scanProc = new ScanProcessor(computer);
			Processor processor = scanProc.getProcessor(host);

			ScanSoftwares scanSoftwares = new ScanSoftwares(computer);
			List<Software> softwares = scanSoftwares.getSoftware(host);

			ScanNic scanNics = new ScanNic(computer);
			List<Nic> nics = scanNics.getNic(host);

			ScanPrinter scanPrinter = new ScanPrinter(computer);
			List<Printer> printers = scanPrinter.getPrinter(host);

			ScanVolume scanVolume = new ScanVolume(computer);
			List<Volume> volumes = scanVolume.getVolumes(host);

			computer.setDescription(hostNameComputer);
			computer.setRam(ramComputer);
			computer.setComputerType(typeComputer);
			computer.setBetriebssystem(os);

			List<Processor> processors = new ArrayList<Processor>();
			processors.add(processor);
			computer.setProzessoren(processors);
			computer.setNics(nics);
			computer.setProgramme(softwares);
			computer.setDrucker(printers);
			computer.setVolumes(volumes);

		} catch (Exception e) {
			System.out.println("hier Fehler");
		}

		return computer;
	}

}
